import axios from 'axios';
import qs from 'qs';
import { getToken } from '@/utils/token';
import { ElMessageBox, ElMessage } from 'element-plus';
import { useUserStore } from '@/store/modules/user';
import { router } from '@/router';

const defaultConfig = {
	timeout: 30000,
	baseURL: import.meta.env.VITE_BASE_URL,
	paramsSerializer: {
		serialize(params) {
			return qs.stringify(params, { allowDots: true });
		},
	},
};

class Service {
	constructor() {
		this.httpInterceptorsRequest();
		this.httpInterceptorsResponse();
	}

	/** Axios实例对象*/
	static axiosInstance = axios.create(defaultConfig);

	/** 请求拦截 */
	httpInterceptorsRequest = () => {
		Service.axiosInstance.interceptors.request.use(
			(config) => {
				const token = getToken();
				if (token) {
					config.headers['Authorization'] = token;
				}
				// 添加No-Token请求头处理
				if (config.axiosConfig?.noToken) {
					config.headers['No-Token'] = 'true';
				}
				return config;
			},
			(error) => {
				return Promise.reject(error);
			}
		);
	};

	/** 响应拦截 */
	httpInterceptorsResponse = () => {
		Service.axiosInstance.interceptors.response.use(
			(response) => {
				return response;
			},
			(error) => {
				return Promise.reject(error);
			}
		);
	};

	// 通用请求
	request = ({ method, url, param, axiosConfig }) => {
		const config = {
			method,
			url,
			...param,
			...axiosConfig,
		};
		return new Promise((resolve, reject) => {
			Service.axiosInstance
				.request(config)
				.then(async (response) => {
					// 增强版blob响应处理（同时检查responseType和Content-Type）
					// 处理blob响应（保持原生axios处理）
					if (response.config?.responseType === 'blob') {
						// 先检查HTTP状态码
						if (response.status !== 200) {
							// 尝试解析错误信息
							const reader = new FileReader();
							reader.onload = () => {
								try {
									const errorData = JSON.parse(reader.result);
									ElMessage.error(errorData.msg || '文件下载失败');
								} catch {
									ElMessage.error(`文件下载失败1 (状态码: ${response.status})`);
								}
							};
							reader.readAsText(response.data);
							return reject(new Error('文件下载失败2'));
						}

						// 从headers中获取文件名
						const contentDisposition = response.headers['content-disposition'];
						let filename = 'file';
						if (contentDisposition) {
							const fileNameMatch = contentDisposition.match(/filename\*?=(?:UTF-8''|")(.+?)(?:"|$)/i);
							if (fileNameMatch && fileNameMatch[1]) {
								filename = decodeURIComponent(fileNameMatch[1]);
							}
						}

						// 构建文件下载结果并立即返回
						return resolve({
							data: response.data,
							filename,
							contentType: response.headers['content-type'],
							status: response.status,
							success: true,
						});
					} else {
						// 处理非blob类型的普通JSON响应
						const { code, data, msg } = response.data || {};
						if (!code) {
							resolve(response.data);
							return;
						}

						switch (code) {
							case 200:
								resolve(data);
								break;
							case 5001:
								ElMessageBox.close();
								ElMessageBox.confirm('登录已过期或登录信息不存在，请重新登录', '提示', {
									confirmButtonText: '重新登录',
									cancelButtonText: '取消',
									type: 'warning',
								})
									.then(async () => {
										await useUserStore().clear();
										await router.push({
											path: '/login',
											query: {
												redirect: router.currentRoute.value.fullPath,
											},
										});
									})
									.catch(() => {});
								break;
							default:
								ElMessage.error(msg || '网络错误');
								reject(response);
						}
					}
				})
				.catch((err) => {
					reject(err);
				});
		});
	};

	// 通用get请求
	get = ({ url, params, axiosConfig }) => {
		return this.request({
			method: 'get',
			url,
			param: { params },
			axiosConfig,
		});
	};

	// 通用post请求
	post = ({ url, data, axiosConfig }) => {
		return this.request({
			method: 'post',
			url,
			param: { data },
			axiosConfig,
		});
	};

	// 通用put请求
	put = ({ url, data, axiosConfig }) => {
		return this.request({
			method: 'put',
			url,
			param: { data },
			axiosConfig,
		});
	};
}

export default new Service();
